package simplelab;

import java.awt.Point;
import java.lang.Math;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import loader.LoadFromConfigFile;
/*
 * The information about the tile's of the world is stored
 * in this class.
 */
//\chapter{saját to-do ezt ki kell venni a beadott anyagból}
//kajánál ha a másik felzabálja és ő azt nem látja akkor benne marad a food listájába a kaja evés közben is figyeljen
//utolsó helyen fordulás felesleges
//előre, körbe fordul maximális
//falakat belevegye a számolásba
//ha mégse venné fel a kaját az ellenfél, akkor visszamenjen
//doksi
//mackró cellák
//debug
// 

//bizonyos körönként változik a pálya, akárnőhet akár csökkenhet, de nem kapunk pontos infót,
//egyszerre változik mindkettő, de bármelyik irányba
public class World {

    public static int worldWidth = LoadFromConfigFile.getMapWidth();
    public static int worldHeight = LoadFromConfigFile.getMapHeight();
    public final static int maxEatPerTurn = LoadFromConfigFile.getMaxFoodEaten();
    public final static int foodLostPerTurn = LoadFromConfigFile.getFoodValueLostAgents();
    public final static int lowEnergy = 200;
    public final static int considerIntelAgeValid = 8;
    public final static int maxFoods = LoadFromConfigFile.getFoodCount();
    public final static int stepCost = LoadFromConfigFile.getStepCost();
    public final static int turnCost = LoadFromConfigFile.getTurnCost();
    public final static int viewDistance = LoadFromConfigFile.getViewDistance();
    public final static int foodlessTurnLimit = 30;
    public final static int maxPlayer = 5;
    public final static int startingEnergy = LoadFromConfigFile.getStartingEnergy();
    public final static int MaxFoodEaten = LoadFromConfigFile.getMaxFoodEaten();
    public final static boolean MapResizeable = LoadFromConfigFile.isMapResizeable();
    public final static int MinMapRegenRound = LoadFromConfigFile.getMinMapRegenRound();
    public final static int MaxMapRegenRound = LoadFromConfigFile.getMaxMapRegenRound();
    public final static int MinMapSize = LoadFromConfigFile.getMinMapSize();
    public final static int MaxMapSize = LoadFromConfigFile.getMaxMapSize();
    public static int macro = 1;
    public static int turn = -1; // The turn we are in, from our perception
    //public Tile[][] tile;
    public int lastChangeTurn;
    //public boolean[][] points = new boolean[worldWidth][worldHeight];
    public static Tile[][] macroblock;
    private static int worldWidthMacro = (int) Math.ceil(worldWidth / (double) macro);
    private static int worldHeigthMacro = (int) Math.ceil(worldHeight / (double) macro);
    public static boolean[][] macroPoints = new boolean[worldWidthMacro][worldHeigthMacro];
    public int lastEnemyPoint;
    public static DebugMap debugMap;
    public boolean enemyOnFood;
    public static ArrayList<Agent> Friendlies;
    public static ArrayList<Agent> Hostiles;
//    public static Agent nowAgent;
    public int myTeamID;
    public int leaderID;
    public int tasksGiven;
    public int teamEnergy;
    //public static Point position;
    public int eating;
    public Point myTarget;
    public static ArrayList<Food> foods;
    public Task mainTask;
    //public int[] matesEnergy;
    Point[] mypos = new Point[deepness - 1];
    //public boolean[][][] mytile = new boolean[deepness - 1][worldWidth][worldHeight];
    private final static int deepness = 5;
    public int whichAgentCame;
    public int[] enemyEating = new int[maxPlayer];
    public boolean[] enemyIsEating = new boolean[maxPlayer];
    private boolean twoStep = true;
    public boolean guiOn = true;
    private int lastCombinate = 1; //az ujratervezést lehet késlelteti
    boolean aSearch = false;
    //private int myAgentCount = 2;
    private int lastTurnBefore = 1; // értéke minimum 1
    //public boolean macroblocks = true;
    //a terület kalkuláció gyorsítása érdekében
    private Position tempPos = new Position();
    private boolean dirx;
    /*
     * Az evés folyamatosságának az ellenörzése
     */
    int enemyEatingTurn;
    private int otherHasAlsoNull;
    private boolean thereWasMapSizeChange = false;
    private Beliefs beliefs;
    private int lastKnowMapSizeChange = 0;
    boolean xDiscovered;
    boolean yDiscovered;
    private static boolean worldWidthGrowing = false;
    private static boolean worldHeightGrowing = false;
    private int mapCouldChanged = 0;
    public int agentNumber = 0;
    private static boolean onDiscovering = false;
    private int lastTurnWhenDiscovered = 0;
    public static int nowAgentIDInFriendlies;
    public static boolean worldReSize = false;
    private boolean notmakeitnull;
    static private boolean worldHeightBigger;
    static private boolean worldWidthBigger;

    private void handleMapChange() {
        removeFoodOutSide();
        //discoverTheMap();
        System.out.println("változott a pályaa");

    }

    private static void removeFoodOutSide() {
        for (int i = foods.size() - 1; i >= 0; i--) {
            if (foods.get(i).position.isLessThan(worldWidth, worldHeight)) {
                System.out.println(foods.get(i).toString() + " kint volt a kaja ezér kivettem");
                foods.remove(i);
            }
        }
    }

    private void discoverTheMap(boolean x, boolean y) {
        System.out.println("2 disc");
        //TODO ki kell nullázni a discovert
        int closestToX = 0, closestToY = 0;
        for (int i = 1; i < Friendlies.size(); i++) {
            Friendlies.get(i).discovering = 0;
            Agent agent = Friendlies.get(i);
            if (x) {
                if (Friendlies.get(closestToX).position.x < agent.position.x) {
                    closestToX = i;
                }
            }
            if (y) {
                if (Friendlies.get(closestToX).position.y <= agent.position.y) {
                    closestToY = i;
                }
            }
        }
        if (x) {
            if (y) {
                Friendlies.get(closestToX).discovering = 3;
            } else {
                Friendlies.get(closestToX).discovering = 1;
            }
        } else if (y) {
            Friendlies.get(closestToY).discovering = 2;
        }

        System.out.println(Friendlies.toString());
        //TODO lehet hogy kell majd
       /* Agent closestToXY = null;
        int distance = worldWidth - closestToX.position.x + worldHeight - closestToY.position.y;
        for (int i = 0; i < Friendlies.size(); i++) {
        Agent agent = Friendlies.get(i);
        if()
        }**/
    }

    public static void fillEmptyBlocks() {
        int prevWorldHeightMacro = worldHeigthMacro;
        int prevWorldWidthMacro = worldWidthMacro;
        worldWidthMacro = (int) Math.ceil(worldWidth / (double) macro);
        worldHeigthMacro = (int) Math.ceil(worldHeight / (double) macro);

        Tile[][] tempMacroblock = new Tile[worldWidthMacro][worldHeigthMacro];
        //System.out.println("macro vl  "+  tempMacroblock.length + " [i] "+ tempMacroblock[0].length);
        int minWidth = Math.min(worldWidthMacro, prevWorldWidthMacro);
        int minHeight = Math.min(worldHeigthMacro, prevWorldHeightMacro);
        for (int x = 0; x < minWidth; x++) {
            System.arraycopy(macroblock[x], 0, tempMacroblock[x], 0, minHeight);
            for (int y = minHeight; y < worldHeigthMacro; y++) {
                tempMacroblock[x][y] = new Tile();
            }
        }
        for (int x = minWidth; x < worldWidth; x++) {
            for (int y = 0; y < worldHeigthMacro; y++) {
                tempMacroblock[x][y] = new Tile();
            }
        }



        boolean[][] tempMacroPoints = new boolean[worldWidthMacro][worldHeigthMacro];
        for (int i = 0; i < minWidth; i++) {
            System.arraycopy(macroPoints[i], 0, tempMacroPoints[i], 0, minHeight);
        }
        for (int k = minWidth; k < worldWidthMacro; k++) {
            for (int l = 0; l < worldHeigthMacro; l++) {
                tempMacroPoints[k][l] = false;
            }

        }
        macroblock = tempMacroblock;
        macroPoints = tempMacroPoints;
    }

    static boolean isThereHostileAgent(Position position) {
        for (int i = 0; i < Hostiles.size(); i++) {
            if (Hostiles.get(i).position.equals(position)) {
                return true;
            }
        }
        return false;
    }

//step/dir 0 felfele 1 jobbra 2 lefele 3 balra    
    private static class FoodReturnType {

        int serial;
        int distance;

        public FoodReturnType(int distance, int serial) {
            this.distance = distance;
            this.serial = serial;
        }

        private FoodReturnType() {
            this.distance = worldHeight + worldWidth;
            this.serial = -1;
        }

        @Override
        public String toString() {
            return "FoodReturnType{" + "serial=" + serial + ", distance=" + distance + '}';
        }
    }

    public World() {
        /*        matesEnergy = new int[10];
        for (int i = 0; i < 10; i++) {
        matesEnergy[i] = 0;
        }*/
        /*tile = new Tile[worldWidth][worldHeight];
        for (int x = 0; x < worldWidth; x++) {
        for (int y = 0; y < worldHeight; y++) {
        tile[x][y] = new Tile();
        }
        }*/
        macroblock = new Tile[worldWidthMacro][worldHeigthMacro];
        for (int x = 0; x < worldWidthMacro; x++) {
            for (int y = 0; y < worldHeigthMacro; y++) {
                macroblock[x][y] = new Tile();
            }
        }

        for (int k = 0; k < worldWidthMacro; k++) {
            for (int l = 0; l < worldHeigthMacro; l++) {
                macroPoints[k][l] = false;
            }
        }
        /*
        for (int k = 0; k < worldHeight; k++) {
        for (int l = 0; l < worldWidth; l++) {
        points[k][l] = false;
        }
        }*/

        for (int i = 0; i < deepness - 1; i++) {
            mypos[i] = new Point();
        }
        lastChangeTurn = deepness;
        if (guiOn) {
            debugMap = new DebugMap(this);
        }
        Friendlies = new ArrayList<Agent>();
        Hostiles = new ArrayList<Agent>();
        foods = new ArrayList<Food>();
        myTeamID = -1;
        leaderID = 0;
        tasksGiven = 0;
        eating = 0;
        myTarget = new Point(-1, -1);
        lastEnemyPoint = 20000;
        enemyOnFood = false;
        teamEnergy = 0;
        whichAgentCame = 0;
        otherHasAlsoNull = 0;
        xDiscovered = false;
        yDiscovered = false;
        for (int i = 0; i < maxPlayer; i++) {
            enemyEating[i] = startingEnergy;
            enemyIsEating[i] = false;
        }
    }

    /*public int teamEnergies() {
    int temp = 0;
    for (int i = 0; i < 10; i++) {
    temp += matesEnergy[i];
    }
    return temp;
    }*/
    public static void error() {
        System.out.println("error " + worldHeight + " width " + worldWidth);
        if (!foods.isEmpty()) {
            FoodReturnType temp = min(Friendlies.get(nowAgentIDInFriendlies).position, Friendlies.get(nowAgentIDInFriendlies).id);
            if (temp.distance == 0) {
                System.out.println("kaja errorban");
                foods.remove(temp.serial);
            }
        }

    }

    //TODO megnézni mire is való ez
    public static void errorBlock() { //TODO para lehet, mert lehet hogy nem lesz jó a nowagent, ha nem jó akkor az adott hiba osztályban kell babrálni
        System.out.println("error block" + worldHeight + " width " + worldWidth + " " + Friendlies.get(nowAgentIDInFriendlies).toString());
        /*if(Friendlies.get(nowAgentIDInFriendlies).position){
        
        }*/

//        worldReSize = false;
        //TODO lépés elött vizsgálni.



        if (isThereHostileAgent(Friendlies.get(nowAgentIDInFriendlies).position)) {
            System.out.println("enemy elötem " + Hostiles.toString());
        } else {

            if (Friendlies.get(nowAgentIDInFriendlies).discovering == 3) {
                if (Friendlies.get(nowAgentIDInFriendlies).position.x < Friendlies.get(nowAgentIDInFriendlies).position.y
                        && Friendlies.get(nowAgentIDInFriendlies).position.x == Friendlies.get(nowAgentIDInFriendlies).lastPosition.x) {
                    worldHeightGrowing = false;
                    worldHeightBigger = false;
                    System.out.println("hgrow false 10");
                    Friendlies.get(nowAgentIDInFriendlies).discovering = 1;
                    System.out.println("discover 1");
                    worldHeight = Friendlies.get(nowAgentIDInFriendlies).position.y;

                } else {
                    worldWidthGrowing = false;
                    worldWidthBigger = false;

                    System.out.println("wgrow false 11");
                    Friendlies.get(nowAgentIDInFriendlies).discovering = 2;
                    
                    worldWidth = Friendlies.get(nowAgentIDInFriendlies).position.x;

                }

            } else if (Friendlies.get(nowAgentIDInFriendlies).discovering > 0) {
                if (Friendlies.get(nowAgentIDInFriendlies).position.x == Friendlies.get(nowAgentIDInFriendlies).lastPosition.x) {
                    worldHeight = Friendlies.get(nowAgentIDInFriendlies).position.y ;
                } else {
                    worldWidth = Friendlies.get(nowAgentIDInFriendlies).position.x;
                }

                worldHeightBigger = false;
                worldWidthBigger = false;
                worldHeightGrowing = false;
                worldWidthGrowing = false;
                System.out.println("hwgrow false 15");
                Friendlies.get(nowAgentIDInFriendlies).discovering = 0;
                onDiscovering = false;
            } else {
                if (Friendlies.get(nowAgentIDInFriendlies).position.x == Friendlies.get(nowAgentIDInFriendlies).lastPosition.x) {
                    
                    worldHeight = Friendlies.get(nowAgentIDInFriendlies).position.y ;
                    worldHeightGrowing = false;
                    worldWidthGrowing = true;
                    System.out.println("hwgrow true wgroe false 16");
//                    worldHeightBigger = true;
//                    worldWidthBigger = false;
                } else {
                    worldWidth = Friendlies.get(nowAgentIDInFriendlies).position.x ;
                    worldHeightGrowing = true;
                    worldWidthGrowing = false;
                    System.out.println("hwgrow false wgroe true 17");
//                    worldHeightBigger = false;
//                    worldWidthBigger = true;

                }
                Friendlies.get(nowAgentIDInFriendlies).discovering = 0;
                onDiscovering = false;
            }
            removeFoodOutSide();
        }
        if (!foods.isEmpty()) {
            FoodReturnType temp = min(Friendlies.get(nowAgentIDInFriendlies).position, Friendlies.get(nowAgentIDInFriendlies).id);
            // if(manhattan(pos, Foods.get(temp)) ==1){
            if (temp.distance == 0) {
                foods.remove(temp.serial);
                System.out.println("kaja block");
            }
            //}
        }
        System.out.println("error " + worldHeight + " width " + worldWidth + " " + Friendlies.get(nowAgentIDInFriendlies).toString());

        Friendlies.get(nowAgentIDInFriendlies).position = Friendlies.get(nowAgentIDInFriendlies).lastPosition;

    }

    /**
     * Belerakja, vagy frissíti a paraméterként kapott food-dal a world foods paraméterét
     * @return igazzal tér vissza, ha bele frissílt, hamissal ha belekerült őj értékként
     * @param food 
     */
    public boolean refreshInsideFood(ArrayList<Food> foodsArray) {
        //System.out.println("eljutott a notinside "+ food.toString());
        for (int l = 0; l < foodsArray.size(); l++) {
            for (int i = foods.size() - 1; i >= 0; i--) {
                if (foods.get(i).position.equals(foodsArray.get(l).position)) {
                    foods.get(i).value = foodsArray.get(l).value;
                    return true;
                }
            }
            foods.add(foodsArray.get(l));
        }
        //System.out.println("food size " + foods.size() );
        for (int i = foods.size() - 1; i >= 0; i--) {
            //ha kint van a pályán kívül a kaja, akkor változott a pálya mérete
            if (foods.get(i).position.isMoreThan(worldWidth, worldHeight)) {
                // && lastKnowMapSizeChange != beliefs.thatTurn) {

                thereWasMapSizeChange = true;
                lastKnowMapSizeChange = beliefs.thatTurn;
                if (worldHeight <= foods.get(i).position.y) {
                    worldHeight = foods.get(i).position.y + 1;
                    worldHeightGrowing = true;
                    if (MinMapRegenRound <= turn - lastTurnWhenDiscovered) {
                        worldWidthGrowing = true;
                    }
                    System.out.println("hgrow true 3");
                }
                if (worldWidth <= foods.get(i).position.x) {
                    // azért kell mert ha egyébként is felderítünk akkor továbbra is derítsük a pályát.
                    worldWidth = foods.get(i).position.x + 1;
                    worldWidthGrowing = true;
                    if (MinMapRegenRound <= turn - lastTurnWhenDiscovered) {
                        worldHeightGrowing = true;
                    }
                    System.out.println("h/wgrow true 4");
                }
                fillEmptyBlocks();
            }
        }
        for (int i = foods.size() - 1; i >= 0; i--) {
            if (isThereHostileAgent(foods.get(i).position)) {
                foods.remove(i);
            }
        }

        return false;
    }

    /* public void foodManages(Beliefs beliefs) {
    for (int i = foods.size() - 1; i >= 0; i--) {
    refreshInsideFood(foods.get(i));
    }
    }*/
    /**
     * visszaadja az adott ágneshez legk�zelebbi kaja sorsz�m�t
     * 
     * @param pos poziciója az ágensnek
     * @param ID adott ágens ID-je
     * @return FoodReturnType amely a kaja távolságát és sorszámát tartalmazza
     */
    public static FoodReturnType min(Position pos, int ID) {
        FoodReturnType temp = new FoodReturnType();
        for (int i = 0; i < foods.size(); i++) {
            if (ID == foods.get(i).ownerID && manhattan(pos, foods.get(i).position) < temp.distance) {
                temp.distance = manhattan(pos, foods.get(i).position);
                temp.serial = i;
            }
        }
        return temp;
    }

    /** a legközelebbi kaját adja vissza az adott pozícióhoz
     * 
     * @param pos
     * @return 
     */
    public static FoodReturnType min(Position pos) {
        FoodReturnType temp = new FoodReturnType();
        for (int i = 0; i < foods.size(); i++) {
            if (manhattan(pos, foods.get(i).position) < temp.distance) {
                temp.distance = manhattan(pos, foods.get(i).position);
                temp.serial = i;
            }
        }
        return temp;
    }

    public Command Manage(Beliefs beliefs) {
        //TODO lehet hogy kelleni fog az hogy az ID az első ágensnek meg legyen jegyezve és amikor az az id jön akkor újratervezni a kaját





        //System.out.println("beliefs " + beliefs.toString());
        this.beliefs = beliefs;

//        nowAgent = Friendlies.get(nowAgentIDInFriendlies);

        //World.turn = beliefs.thatTurn;

//        Agent nowAgent = new Agent(beliefs.id,beliefs.team,beliefs.energy,Friendlies.get(nowAgentIDInFriendlies).position,Friendlies.get(nowAgentIDInFriendlies).direction);
//        if (beliefs.mapSize != null && worldHeight != beliefs.mapSize.y && worldWidth != beliefs.mapSize.x) {
//            handleMapChange();
//            System.out.println("map regenet");
//            worldHeight = beliefs.mapSize.y;
//            worldWidth = beliefs.mapSize.x;
//
//
//
//            int prevWorldHeightMacro = worldHeigthMacro;
//            int prevWorldWidthMacro = worldWidthMacro;
//            worldWidthMacro = (int) Math.ceil(worldWidth / (double) macro);
//            worldHeigthMacro = (int) Math.ceil(worldHeight / (double) macro);
//
//            Tile[][] tempMacroblock = new Tile[worldWidthMacro][worldHeigthMacro];
//            //System.out.println("macro vl  "+  tempMacroblock.length + " [i] "+ tempMacroblock[0].length);
//            int minWidth = Math.min(worldWidthMacro, prevWorldWidthMacro);
//            int minHeight = Math.min(worldHeigthMacro, prevWorldHeightMacro);
//            for (int x = 0; x < minWidth; x++) {
//                System.arraycopy(macroblock[x], 0, tempMacroblock[x], 0, minHeight);
//                for (int y = minHeight; y < worldHeigthMacro; y++) {
//                    tempMacroblock[x][y] = new Tile();
//                }
//            }
//            for (int x = minWidth; x < worldWidth; x++) {
//                for (int y = 0; y < worldHeigthMacro; y++) {
//                    tempMacroblock[x][y] = new Tile();
//                }
//            }
//
//
//            
//            boolean[][] tempMacroPoints = new boolean[worldWidthMacro][worldHeigthMacro];
//            for (int i = 0; i < minWidth; i++) {
//                System.arraycopy(macroPoints[i], 0, tempMacroPoints[i], 0, minHeight);
//            }
//            for (int k = minWidth; k < worldWidthMacro; k++) {
//                for (int l = 0; l < worldHeigthMacro; l++) {
//                    tempMacroPoints[k][l] = false;
//                }
//
//            }
//            macroblock = tempMacroblock;
//            macroPoints = tempMacroPoints;
//
//        }

//        try {
//            System.out.println(Friendlies.get(nowAgentIDInFriendlies) + " tun " + turn);
//            if (Friendlies.get(nowAgentIDInFriendlies).lastPosition.x > Friendlies.get(nowAgentIDInFriendlies).position.x) {//&& (turn - lastTurnWhenDiscovered) >= MinMapRegenRound) {
//                thereWasMapSizeChange = true;
//                mapCouldChanged = 1;
//                worldWidth = Friendlies.get(nowAgentIDInFriendlies).position.x + 1;
//                worldHeightGrowing = true;
//                System.out.println("hgrow true 5");
//                System.out.println("kissebb x" + Friendlies.get(nowAgentIDInFriendlies).position.toString() + " pos " + Friendlies.get(nowAgentIDInFriendlies).lastPosition.toString() + " fr " + Friendlies.get(nowAgentIDInFriendlies).toString());
//            }
//            if (Friendlies.get(nowAgentIDInFriendlies).lastPosition.y > Friendlies.get(nowAgentIDInFriendlies).position.y) {// && (turn - lastTurnWhenDiscovered) >= MinMapRegenRound) {
//                worldHeightGrowing = false;
//                System.out.println("hgrow false 6");
//                if (Friendlies.get(nowAgentIDInFriendlies).lastPosition.x <= Friendlies.get(nowAgentIDInFriendlies).position.x) {
//                    worldWidthGrowing = true;
//                    System.out.println("wgrow true 7");
//                } else {
//                    lastTurnWhenDiscovered = turn;
//                }
//                thereWasMapSizeChange = true;
//                mapCouldChanged = 1;
//                worldHeight = Friendlies.get(nowAgentIDInFriendlies).position.y + 1;
//                System.out.println("kissebb y" + Friendlies.get(nowAgentIDInFriendlies).position.toString() + " pos " + Friendlies.get(nowAgentIDInFriendlies).lastPosition.toString() + " fr " + Friendlies.get(nowAgentIDInFriendlies).toString());
//            }
//
//        } catch (NullPointerException e) {
//            System.out.println("első körbeli hiba");
//        }

//        System.out.println("3 " +Friendlies.get(nowAgentIDInFriendlies).toString());
//        System.out.println("elso2 " + worldWidth + " h: " + worldHeight + " pos " + Friendlies.get(nowAgentIDInFriendlies).position);
        if (thereWasMapSizeChange) {
            //TODO megoldani, hgoy csak egyszer fusson 
            removeFoodOutSide();
            thereWasMapSizeChange = false;
        }

//        System.out.println("41 " + World.Friendlies.get(0).toString());
//        if (!Friendlies.get(nowAgentIDInFriendlies).position.equals(Friendlies.get(nowAgentIDInFriendlies).lastPosition)) {
//            handleMapChange();
//
//        }
       /* if (mapCouldChanged > 0 || mapCouldChanged < 6 ) {
        mapCouldChanged++;
        if (Friendlies.get(nowAgentIDInFriendlies).position.x < worldWidth) {
        worldWidth = Friendlies.get(nowAgentIDInFriendlies).position.x;
        }
        if (Friendlies.get(nowAgentIDInFriendlies).position.x < worldHeight) {
        worldHeight = Friendlies.get(nowAgentIDInFriendlies).position.y;
        }
        }*/


        lastChangeTurn++;

        //a frissítés (refreshTile) után 4 körig még megengedi a hátra forgást, ez a változó ezt szabályozza
        ///  System.out.println(Math.ceil(worldWidth /(double)macro)+"sdf " +(worldWidth / macro)+ "  fs "+ (worldWidth / (double) macro) );
        eating--;
        //turn = beliefs.

        //System.out.println("agents " + Friendlies.get(nowAgentIDInFriendlies).toString());
        if (Friendlies.get(nowAgentIDInFriendlies).energy < lowEnergy) {
            System.out.println("agent energy " + Friendlies.get(nowAgentIDInFriendlies).energy);
            return new Command(Command.Action.Wait, 0, 0);
        }
        //TODO megcisnálni, hogy ha az ellenség több kaját eszik egyszerre akkor is jó maradjon
        //matesEnergy[beliefs.id] = beliefs.energy;
        int enemyPoint = (int) (teamEnergy / beliefs.ratio) - teamEnergy;


        //System.out.println(enemyPoint + " most " + lastEnemyPoint + " elötte " + teamEnergy + " enyém " + enemyEating[whichAgentCame]);
        //átállítja ha az ellenség kajálni kezd
        /*if (enemyPoint > lastEnemyPoint + maxEatPerTurn / 4) {
        
        enemyOnFood = true;
        } else  {
        //ha befejezte az ellenség a kajálást, frissít
        if (enemyOnFood) {
        System.out.println("enemy miatti frissítés ");
        refreshTiles();
        }
        enemyOnFood = false;
        }*/


        //ha az ellenség az adott ágens elött kajált, akkor a flagat aktíváljuk, majd ha abba hagyta a kajálást akkor frissítjük a mappot
       /* if(enemyPoint> enemyEating[whichAgentCame]){
        enemyIsEating[whichAgentCame] = true;
        }else if(enemyIsEating[whichAgentCame]){
        enemyIsEating[whichAgentCame] =false;
        
        System.out.println("enemy miatti frissítés ");
        refreshTiles();
        }
        
        
        enemyEating[whichAgentCame] = enemyPoint;
        if(++whichAgentCame == Friendlies.size()){
        whichAgentCame =0;
        }*/
        //System.out.println("agent pos 2 " + Friendlies.get(nowAgentIDInFriendlies).position.toString());



        //Friendlies.get(nowAgentIDInFriendlies).lastPosition = Friendlies.get(nowAgentIDInFriendlies).position;
        //System.out.println("nowagent \t" + Friendlies.get(nowAgentIDInFriendlies).toString());

        System.out.println("4 " + Friendlies.get(nowAgentIDInFriendlies).toString());

//        System.out.println("3 turn " + Friendlies.get(nowAgentIDInFriendlies).toString());
        System.out.println("map " + MaxMapRegenRound + " trun " + turn + " lasttrun " + lastTurnWhenDiscovered);
        if (MaxMapRegenRound < turn - lastTurnWhenDiscovered) {
            discoverTheMap(true, true);
            lastTurnWhenDiscovered = turn;
        }

        if ((worldHeightGrowing || worldWidthGrowing) && !onDiscovering) {
            System.out.println("map regenet " + worldHeightGrowing + "  " + worldWidthGrowing);
            onDiscovering = true;
            lastTurnWhenDiscovered = turn;
            discoverTheMap(worldWidthGrowing, worldHeightGrowing);
//            if (worldHeightGrowing) {
//                worldHeight++;
//            }
//            if (worldWidthGrowing) {
//                worldWidth++;
//            }
//
//            worldHeightGrowing = false;
//            worldWidthGrowing = false;
//            fillEmptyBlocks();

        }

        if (Friendlies.get(nowAgentIDInFriendlies).discovering > 0) {

            notmakeitnull = true;
            if (Friendlies.get(nowAgentIDInFriendlies).discovering == 2) {
                if (worldHeightBigger) {
                    worldHeight++;
                    fillEmptyBlocks();
                }
                if (worldHeight - 1 == Friendlies.get(nowAgentIDInFriendlies).position.y) {

                    worldHeightBigger = true;
//                    worldReSize = true;
                }
                //Friendlies.get(nowAgentIDInFriendlies).position = new Position(Friendlies.get(nowAgentIDInFriendlies).position.x, Friendlies.get(nowAgentIDInFriendlies).position.y + 1);
                if (Friendlies.get(nowAgentIDInFriendlies).direction != 2) {
                    makeItNull(Friendlies.get(nowAgentIDInFriendlies).position, Friendlies.get(nowAgentIDInFriendlies).direction, new Task(new Point(1, 2)));
                    return new Command(Command.Action.Turn, 2, 0);
                }

//                Friendlies.get(nowAgentIDInFriendlies).oneStepAhaed(2);
                makeItNull(Friendlies.get(nowAgentIDInFriendlies).position, Friendlies.get(nowAgentIDInFriendlies).direction, new Task(new Point(0, 2)));

                return new Command(Command.Action.Step, 2, 0);
            } else if (Friendlies.get(nowAgentIDInFriendlies).discovering == 1) {
                if (worldWidthBigger) {
                    worldWidth++;
                    fillEmptyBlocks();
                }
                if (worldWidth - 1 == Friendlies.get(nowAgentIDInFriendlies).position.x) {

                    worldWidthBigger = true;
//                    worldReSize = true;
                }
                //Friendlies.get(nowAgentIDInFriendlies).position = new Position(Friendlies.get(nowAgentIDInFriendlies).position.x + 1, Friendlies.get(nowAgentIDInFriendlies).position.y);
                if (Friendlies.get(nowAgentIDInFriendlies).direction != 1) {
                    makeItNull(Friendlies.get(nowAgentIDInFriendlies).position, Friendlies.get(nowAgentIDInFriendlies).direction, new Task(new Point(1, 1)));
                    return new Command(Command.Action.Turn, 1, 0);
                }
//                Friendlies.get(nowAgentIDInFriendlies).oneStepAhaed(1);
                makeItNull(Friendlies.get(nowAgentIDInFriendlies).position, Friendlies.get(nowAgentIDInFriendlies).direction, new Task(new Point(0, 1)));

                return new Command(Command.Action.Step, 1, 0);
            } else if (Friendlies.get(nowAgentIDInFriendlies).discovering == 3) {

                if (Friendlies.get(nowAgentIDInFriendlies).position.x < Friendlies.get(nowAgentIDInFriendlies).position.y) {
                    if (worldHeightBigger) {
                        worldHeight++;
                        fillEmptyBlocks();
                    }
                    if (worldHeight == Friendlies.get(nowAgentIDInFriendlies).position.y - 1) {

                        worldHeightBigger = true;
//                        worldReSize = true;
                    }
                    if (Friendlies.get(nowAgentIDInFriendlies).direction != 2) {
                        makeItNull(Friendlies.get(nowAgentIDInFriendlies).position, Friendlies.get(nowAgentIDInFriendlies).direction, new Task(new Point(1, 2)));

                        return new Command(Command.Action.Turn, 2, 0);
                    }
                    //Friendlies.get(nowAgentIDInFriendlies).position = new Position(Friendlies.get(nowAgentIDInFriendlies).position.x, Friendlies.get(nowAgentIDInFriendlies).position.y + 1);
//                    Friendlies.get(nowAgentIDInFriendlies).oneStepAhaed(2);
                    makeItNull(Friendlies.get(nowAgentIDInFriendlies).position, Friendlies.get(nowAgentIDInFriendlies).direction, new Task(new Point(0, 2)));

                    return new Command(Command.Action.Step, 2, 0);
                } else {
                    if (worldWidthBigger) {
                        worldWidth++;
                        fillEmptyBlocks();
                    }
                    if (worldWidth - 1 == Friendlies.get(nowAgentIDInFriendlies).position.x) {


                        worldWidthBigger = true;
//                        worldReSize = true;
                    }
                    if (Friendlies.get(nowAgentIDInFriendlies).direction != 1) {
                        makeItNull(Friendlies.get(nowAgentIDInFriendlies).position, Friendlies.get(nowAgentIDInFriendlies).direction, new Task(new Point(1, 1)));

                        return new Command(Command.Action.Turn, 1, 0);
                    }
                    //Friendlies.get(nowAgentIDInFriendlies).position = new Position(Friendlies.get(nowAgentIDInFriendlies).position.x + 1, Friendlies.get(nowAgentIDInFriendlies).position.y);
//                    Friendlies.get(nowAgentIDInFriendlies).oneStepAhaed(1);
                    makeItNull(Friendlies.get(nowAgentIDInFriendlies).position, Friendlies.get(nowAgentIDInFriendlies).direction, new Task(new Point(0, 1)));

                    return new Command(Command.Action.Step, 1, 0);
                }
            }
        }
        //Todo törölni
        notmakeitnull = false;
//        System.out.println("c1 " +Friendlies.get(nowAgentIDInFriendlies).toString());

//        System.out.println("42 " + World.Friendlies.get(0).toString());



//        System.out.println("61 " +Friendlies.get(nowAgentIDInFriendlies).toString());


        lastEnemyPoint = enemyPoint;
        //ha maxfood+1 akkor kaj�l
        FoodReturnType temp = new FoodReturnType();
        if (foods.size() > 0) {
            //foodManages(beliefs);
//            System.out.println("c55");
            temp = min(Friendlies.get(nowAgentIDInFriendlies).position, Friendlies.get(nowAgentIDInFriendlies).id);
            try {
                if (Friendlies.get(nowAgentIDInFriendlies).id == Friendlies.get(0).id) {
                    findAgentsForFood();
                }
            } catch (IndexOutOfBoundsException ex) {
                //Első körben ez hibát dob
                System.out.println("Elkezdtük");
            }




            //System.out.println(Friendlies.get(0) + " sdf " + Friendlies.get(nowAgentIDInFriendlies)ID);
            // System.out.println(temp + " sdf " + Friendlies.get(nowAgentIDInFriendlies)ID);

            if (temp.distance == 0) {
                int numberInLine = temp.serial;
                int eatValue = (foods.get(numberInLine).value < maxEatPerTurn) ? foods.get(numberInLine).value : 200;
                foods.get(numberInLine).value -= maxEatPerTurn + foodLostPerTurn;
                //kit�rli ha a k�r v�gi �tkez�s ut�n a kaja �rt�ke 1 al� cs�kkent

                if (foods.get(numberInLine).value < 1) {
                    foods.remove(numberInLine);
                    System.out.println("kaja lett kivéve");
                    refreshTiles();
                }

                calculateNewTeamEnergy(-eatValue);
                return new Command(Command.Action.Eat, 0, 0);
            } else if (temp.distance < worldHeight + worldWidth) {
                mainTask = findPath(Friendlies.get(nowAgentIDInFriendlies).position, temp.serial, Friendlies.get(nowAgentIDInFriendlies).direction);
                //debughoz
                mainTask.profit = 9000;
                return executeMaintask();
            }
        }

//                System.out.println("62 " +Friendlies.get(nowAgentIDInFriendlies).toString());


//        System.out.println("agent pos 3 " + Friendlies.get(nowAgentIDInFriendlies).position.toString());

        //megkeresi a k�vetkez� kaj�t
        if (temp.serial != -1) {
            mainTask = findTarget(Friendlies.get(nowAgentIDInFriendlies).position, Friendlies.get(nowAgentIDInFriendlies).direction, temp);
            //debughozm
//            System.out.println("c66");
            mainTask.profit = 8000;
        } else {
            //ha az utolsó körben sikerült lefutnia egy combinatenek és még van pár lépés benne akkor nem változtatja
//            if (lastChangeTurn > lastCombinate) {
                //OneTile(Friendlies.get(nowAgentIDInFriendlies).position, Friendlies.get(nowAgentIDInFriendlies).direction);
                mainTask = Combinate(Friendlies.get(nowAgentIDInFriendlies).position.clone(), Friendlies.get(nowAgentIDInFriendlies).direction);
                lastChangeTurn = 0;
//                System.out.println("c77");
//            }
        }
        //  System.out.println("agent pos 4 " + Friendlies.get(nowAgentIDInFriendlies).position.toString());

        return executeMaintask();
    }

    public Command executeMaintask() {
        // System.out.println("a main task  " + nowAgent + " " + mainTask.toString());
//                System.out.println("7 " +Friendlies.get(nowAgentIDInFriendlies).toString());
//        System.out.println("c43 " + World.Friendlies.get(0).toString());
        if (!mainTask.task.isEmpty()) {

            Friendlies.get(nowAgentIDInFriendlies).direction = makeItNull(Friendlies.get(nowAgentIDInFriendlies).position, Friendlies.get(nowAgentIDInFriendlies).direction, mainTask);

//            System.out.println("44 " + World.Friendlies.get(0).toString());
            int mainTaskX = mainTask.task.get(0).x;
            int mainTaskY = mainTask.task.get(0).y;
            mainTask.task.remove(0);
            if (mainTaskX == 0) {
                calculateNewTeamEnergy(stepCost);
//                Friendlies.get(nowAgentIDInFriendlies).oneStepAhaed(mainTaskY);
//                System.out.println("45 " + World.Friendlies.get(0).toString());
                return new Command(Command.Action.Step, mainTaskY, 0);
            } else if (mainTaskX == 1) {
                calculateNewTeamEnergy(turnCost);
                return new Command(Command.Action.Turn, mainTaskY, 0);
            } else if (mainTaskX == 2) {
                return new Command(Command.Action.Wait, mainTaskY, 0);
            } else {
                System.out.println("no itt nem tudom mennyi eszik meg!!");
                return new Command(Command.Action.Eat, mainTaskY, 0);
            }
        } else {
            //calculateNewTeamEnergy(stepCost);
            //return new Command(Command.Action.Step, 0, 0);
            System.out.println("                waittel mert nincs terv");
            return new Command(Command.Action.Wait, 0, 0);
        }

    }

    /** frissíti a csapat energia szintjét
     * 
     * @param cost  a lépést pozítiv értékként kell megadni, a kajálást negatívként
     */
    void calculateNewTeamEnergy(int cost) {

        for (int l = 0; l < Friendlies.size(); l++) {
            if (Friendlies.get(l).id == Friendlies.get(nowAgentIDInFriendlies).id) {
                Friendlies.get(l).energy -= cost;
                teamEnergy -= cost;
            }
        }
    }

    private void findAgentsForFood() {
        int min = worldHeight + worldWidth;

        //megnézzük hogy melyik ágenshez van legközelebb a kaja
        for (int i = foods.size() - 1; i >= 0; i--) {
            for (int l = Friendlies.size() - 1; l >= 0; l--) {
                if (min > manhattan(foods.get(i).position, Friendlies.get(l).position)) {
                    min = manhattan(foods.get(i).position, Friendlies.get(l).position);
                    foods.get(i).ownerID = Friendlies.get(l).id;
                }
            }
            min = worldHeight + worldWidth;
        }

    }

    //kikeresi a legk�zelebbi kaj�t
    private Task findTarget(Position pos, int dir, FoodReturnType temp) {
        if (temp.distance == 0) {

            Task ret = new Task();
            foods.get(temp.serial).value -= maxEatPerTurn + foodLostPerTurn;
            if (foods.get(temp.serial).value < 1) {
                System.out.println("most törlünk egy foodog" + foods.get(temp.serial).value);
                foods.remove(temp.serial);
                refreshTiles();
            }

            ret.task.add(new Point(3, 0));
            return ret;
        }
        //ha nincs elérhető kaja akkor újratervezés
        if (temp.serial == -1) {
            System.out.println("Szerintem ez nem szükségés, de mindjárt");
            return Combinate(pos, dir);
        }
        return findPath(pos, temp.serial, dir);
    }

    boolean nextToTheAgent(Agent agent) {
        if (Math.abs(Friendlies.get(nowAgentIDInFriendlies).position.x - agent.position.x) <= 1 && Math.abs(Friendlies.get(nowAgentIDInFriendlies).position.x - agent.position.x) <= 1) {
            return true;
        }
        return false;
    }

    /**
     * Meghatározza az utat a kajáig
     * 
     * @param pos agent poziciója
     * @param seq az adott kaja sorzsáma
     * @param agents agánsek listája
     * @param dir milyen irányba áll az adott ágens
     * @return 
     */
    private Task findPath(Position pos, int seq, int dir) {
        Task ret = new Task();
        Food closest = foods.get(seq);
        /*if (aSearch) {
        int dirx = -1, diry = -1;
        if (closest.position.x > pos.x) {
        dirx = 1;
        } else if (closest.position.x < pos.x) {
        dirx = 3;
        } else if (closest.position.y > pos.y) {
        diry = 2;
        } else if (closest.position.y < pos.y) {
        diry = 0;
        }
        
        
        //}
        Point enemyPos = null;
        
        FoodReturnType foodTemp;
        
        /* for (int i = 0; i < Hostiles.size(); i++) {
        if( nextToTheAgent(Hostiles.get(i)) && Hostiles.get(i).stillInTheSameBlock > 5){
        
        }
        
        
        }*/



        /*if (agents != null && agents.size() > 0) { // 
        int n = 0;
        for (int i = 0; i < agents.size(); i++) {
        //if (agents.get(i).team != myTeamID) { // TODO megcsinálni, az összes ellenséges ágensre
        if (agents.get(i).position.equals(pos) ) {
        enemyPos = agents.get(i).position;
        n = i;
        }
        //System.out.println(" itt van " + enemy.size());
        //ha van ellenséges ágens a láthatáron akkor megnézzük hogy mi vagyunk-e közelebb a kajához
        //ha igen akkor oda megyünk, egyébként tovább felderítünk
        if (enemyPos != null) {
        min(enemyPos)
        if ( .distance == 0) {
        
        //törli ha az ellenség közelebb van a gép
        } else if (manhattan(enemyPos, closest.position) < manhattan(pos, closest.position) && agents.get(n).IsFacing(closest.position)) {
        // System.out.println(" törlés előtt "+Foods.size());
        Foods.remove(closest);
        // System.out.println(" törlés utn "+Foods.size());
        if (Foods.size() > 0) {
        return findTarget(pos, agents, dir);
        } else {
        return Combinate(pos, dir);
        }
        }
        }
        enemyPos = null;
        }
        }*/
        foods.get(seq).ownerID = Friendlies.get(nowAgentIDInFriendlies).id;
        Point tempPoint = null;
        Position whereIwillStep = new Position(Friendlies.get(nowAgentIDInFriendlies).position.x, Friendlies.get(nowAgentIDInFriendlies).position.y);

        //TODO DEBUG world height width
        /*if (closest.position.x > pos.x) {
        ++whereIwillStep.y;
        if (!isThereHostileAgent(whereIwillStep)) {
        tempPoint = new Point(0, 1);
        } else {
        tempPoint = whereIStep(true, pos);
        }
        } else if (closest.position.x < pos.x) {
        --whereIwillStep.y;
        if (!isThereHostileAgent(whereIwillStep)) {
        tempPoint = new Point(0, 3);
        } else {
        tempPoint = whereIStep(true, pos);
        }
        } else if (closest.position.y > pos.y) {
        ++whereIwillStep.x;
        if (!isThereHostileAgent(whereIwillStep)) {
        tempPoint = new Point(0, 2);
        } else {
        tempPoint = whereIStep(false, pos);
        }
        } else if (closest.position.y < pos.y) {
        --whereIwillStep.x;
        if (!isThereHostileAgent(whereIwillStep)) {
        tempPoint = new Point(0, 0);
        } else {
        tempPoint = whereIStep(false, pos);
        }
        }*/

        if (closest.position.x > pos.x) {

            tempPoint = new Point(0, 1);

        } else if (closest.position.x < pos.x) {
            tempPoint = new Point(0, 3);

        } else if (closest.position.y > pos.y) {
            tempPoint = new Point(0, 2);

        } else if (closest.position.y < pos.y) {
            tempPoint = new Point(0, 0);

        }





        if (tempPoint.y != dir) {
            ret.task.add(new Point(1, tempPoint.y));
        } else {
            ret.task.add(tempPoint);
        }


        return ret;
    }

    /**
     * visszadja hogy merre kell lépni, ha elakadtunk
     * @param dir 
     * @param pos
     * @return 
     */
    Point whereIStep(boolean isDirX, Position pos) {
        Point tempPoint;
        System.out.println("elakadtunk " + pos.toString() + "  ");
        if (isDirX) {
            if (pos.y < worldHeight / 2) {
                tempPoint = new Point(0, 2);
            } else {
                tempPoint = new Point(0, 0);
            }
        } else {
            if (pos.x < worldWidth / 2) {
                tempPoint = new Point(0, 1);
            } else {
                tempPoint = new Point(0, 3);
            }
        }
        return tempPoint;
    }

    /**
     * megadja hogy az adott mezőn található-e ellenséges ágens
     * @param pos az adott helyre kívánunk lépni
     * @return igaz ha van ott ágen, hamis ha nincs ott ágens
     */
    private static boolean isThereAgent(Position pos) {

        for (int i = 0; i < Friendlies.size(); i++) {
            if (Friendlies.get(i).position.equals(pos)) {
                return true;
            }
        }

        return isThereHostileAgent(pos);
    }

    public static int manhattan(Position first, Position second) {
        return Math.abs(first.x - second.x) + Math.abs(first.y - second.y);

    }

    public Task CalculateMacro(Position pos, int dir, int[] actions, int turnCount) {
        int plus;

        Task returner = new Task();
        //megmondja hogy x tengelyre párhuzamos-e a dir
        tempPos.x = pos.x / macro;
        tempPos.y = pos.y / macro;
        //segéd változók a az adott pont kiszámításához
        int tempX = 0, tempY = 0;
        for (int k = 0; k < deepness; k++) {
            /**
             * actions: 
             * 0 move forward
             * 1 turn right
             * 2 turn back
             * 3 turn left
             */
            if (actions[k] != 0) {
                dir = (dir + actions[k]) % 4;

                returner.task.add(new Point(1, dir));

            }
            //how the pos will change
            if (dir == 2 || dir == 1) {
                plus = 1;
            } else {
                plus = -1;
            }

            dirx = (dir % 2 == 0);

            //pos moving
            if (actions[k] == 0) {
                if (dirx) {
                    tempPos.y += plus;
                    /* if ((tempPos.y >= (worldHeight-viewDistance-2)/macro  && dir == 2) || (tempPos.y <= viewDistance/macro && dir == 0 )) {
                    return new Task();
                    }*/
                } else {
                    tempPos.x += plus;
                    /*if ((tempPos.x >= (worldWidth-viewDistance-2)/macro  && dir == 1) || (tempPos.x <= viewDistance/macro && dir == 3 )) {
                    return new Task();
                    }*/
                }
                if (k == 0 && isThereAgent(tempPos)) {
                    //System.out.println("asddf ");
                    return new Task();
                }
                returner.task.add(new Point(0, dir));
            }

            //put the title
            for (int i = 1; i < 10 / macro + 1; ++i) {
                if (dirx) {
                    tempY = tempPos.y + plus * i;
                } else {
                    tempX = tempPos.x + plus * i;
                }
                for (int l = -1 * i; l <= i; ++l) {
                    if (dirx) {
                        tempX = tempPos.x + l;
                    } else {
                        tempY = tempPos.y + l;
                    }
                    if (tempX > -1 && tempX < worldWidthMacro && tempY > -1 && tempY < worldHeigthMacro) {
                        macroPoints[tempX][tempY] = true;

                    }
                    //ha kifele néz else if()
                }
            }

        }
        //bool t�mb, 
        for (int i = 0; i < worldWidthMacro; i++) {
            for (int l = 0; l < worldHeigthMacro; l++) {
                ///System.out.println(l + " l "+ i + " w "+ worldHeight / macro);
                if (macroPoints[i][l]) {
                    returner.profit += macroblock[i][l].value;
                    macroPoints[i][l] = false;
                }
            }
        }
//        returner.profit = returner.profit * 100 / ((deepness - turnCount) * stepCost + turnCount * turnCost);
        return returner;




    }

    /**
     * megnézi hogy az adott lépéssorozat bent van-e a mappon belül
     * @param tempDeep
     * @param pos
     * @param dir
     * @return 
     */
    private boolean inSide(int[] tempDeep, Position pos, int dir) {
        int plus;
        int i = 0;
        int tempX = pos.x, tempY = pos.y;
        do {
            if (tempDeep[i] != 0) {
                dir = (dir + tempDeep[i]) % 4;
            }
            //how the pos will change
            if (dir == 2 || dir == 1) {
                plus = 1;
            } else {
                plus = -1;
            }
            dirx = dir % 2 == 0;
            //pos moving
            if (tempDeep[i] == 0) {
                if (dirx) {
                    tempY += plus;
                } else {
                    tempX += plus;
                }
            }
        } while (!((tempY > worldHeight - viewDistance - 2 && dir == 2)
                || (tempY < viewDistance && dir == 0) || (tempX > worldWidth - viewDistance - 2 && dir == 1)
                || (tempX < viewDistance && dir == 3)) && i++ < tempDeep.length - 1);
        if (i == tempDeep.length) {
            return true;
        }
        return false;
    }

    public Task ReCombinateMacro(int deep, Position pos, int dir, int[] temp) {
        Task tempTask, maxProfit = new Task();




        int z = 1;
        //a kaja utáni első három körben a hátrafordulás is engedélyezett
        /*if (eating > 0) {
        z = 1;
        }*/
        int[] tempDeep = new int[deepness];
        if (isThereAgent(pos.oneStepAhaed(dir))) {
            maxProfit = new Task();
            for (int n = 1; n < 4; n += z) {
                tempDeep[0] = n;
                if (inSide(tempDeep, pos, dir)) {
                    tempTask = CalculateMacro(pos, dir, tempDeep, 1);
                    if (tempTask.profit > maxProfit.profit) {
//                        System.out.println("task asd1 " + tempTask.toString() + " " + Friendlies.get(nowAgentIDInFriendlies).toString());
                        maxProfit = tempTask;
                    }
                }
            }
            tempDeep[0] = 0;



            for (int n = 1; n < 4; n += z) {
                tempDeep[0] = n;
                for (int l = 0 + 1; l < deepness - lastTurnBefore; l++) {
                    for (int j = 1; j < 4; j += z) {
                        tempDeep[l] = j;
                        if (inSide(tempDeep, pos, dir)) {
                            tempTask = CalculateMacro(pos, dir, tempDeep, 2);
                            if (tempTask.profit > maxProfit.profit) {
                                maxProfit = tempTask;
//                                System.out.println("task asd2 " + tempTask.toString() + " " + Friendlies.get(nowAgentIDInFriendlies).toString());
                            }
                        }
                    }
                    tempDeep[l] = 0;
                }

            }
        } else {
            for (int i = 0; i < deepness; ++i) {
                tempDeep[i] = 0;
            }
            maxProfit = CalculateMacro(pos, dir, tempDeep, 0);
//            System.out.println("maxprofit2 "+ maxProfit.toString());
            for (int i = deepness - lastTurnBefore; i > -1; --i) {
                for (int n = 1; n < 4; n += z) {
                    tempDeep[i] = n;
                    if (inSide(tempDeep, pos, dir)) {
                        tempTask = CalculateMacro(pos, dir, tempDeep, 1);
                        if (tempTask.profit > maxProfit.profit) {
//                            System.out.println("task1 " + tempTask.toString() + " " + Friendlies.get(nowAgentIDInFriendlies).toString());
                            maxProfit = tempTask;
                        }
                    }
                }
                tempDeep[i] = 0;
            }
//            System.out.println("maxprofit3 "+ maxProfit.toString());
            if (twoStep) {
                for (int i = deepness - lastTurnBefore-1; i >=  0; i--) {

                    for (int n = 1; n < 4; n += z) {
                        tempDeep[i] = n;
                        for (int l = deepness - lastTurnBefore; l > i; --l) {
                            for (int j = 1; j < 4; j += z) {
                                tempDeep[l] = j;
                                if (inSide(tempDeep, pos, dir)) {
                                    tempTask = CalculateMacro(pos, dir, tempDeep, 2);
                                    if (tempTask.profit > maxProfit.profit) {
                                        maxProfit = tempTask;
//                                        System.out.println("task2 " + tempTask.toString() + " " + Friendlies.get(nowAgentIDInFriendlies).toString());
                                    }
                                }
                            }
                            tempDeep[l] = 0;
                        }

                    }
                    tempDeep[i] = 0;
                }


            }
        }
        //}
//        System.out.println("maxprofit4 "+ maxProfit.toString());
        if (maxProfit.profit == 0) {
            return new Task();
        }
        return maxProfit;
    }

    public Task Combinate(Position pos, int dir) {
        Task maxProfit;
        maxProfit = new Task();

        maxProfit = ReCombinateMacro(0, pos, dir, null);
        if (maxProfit.profit == 0) {
            if (Friendlies.get(nowAgentIDInFriendlies).noValueableStep) {
                if (otherHasAlsoNull > Friendlies.size() - 3) {
                    Friendlies.get(nowAgentIDInFriendlies).noValueableStep = false;
                    for (int i = 0; i < worldWidthMacro; i++) {
                        for (int l = 0; l < worldHeigthMacro; l++) {
                            macroblock[i][l].value = 4;
                        }
                    }
                    otherHasAlsoNull = 0;
                    maxProfit = ReCombinateMacro(0, pos, dir, null);
                } else {
                    maxProfit.task.add(new Point(2, 0));
                }
            } else {
                ++otherHasAlsoNull;
                Friendlies.get(nowAgentIDInFriendlies).noValueableStep = true;
                maxProfit.task.add(new Point(2, 0));
            }
        }
        //}
        return maxProfit;
    }

    //kinull�zza a l�tott mez�k �rt�k�t
    //átállítja a beliefseket, az akció utánira, azaz lépteti vagy elforgatja a nézetet
    //debugonhoz kell ez
    public int makeItNull(Position pos, int dir, Task maxProfit) {
        if (notmakeitnull) {
            System.out.println("Make it " + pos.toString() + " " + maxProfit.toString());
        }
        int plus;
        int maxProfitX = maxProfit.task.get(0).x,
                maxProfitY = maxProfit.task.get(0).y;

//        System.out.println("maxprof "+ maxProfit.toString() + " pos " + pos.toString());

        // turning x = 1, y =  the dir
        if (maxProfitX == 1) {
            dir = maxProfitY;
        }
        //how the pos will change
        if (dir == 2 || dir == 1) {
            plus = 1;
        } else {
            plus = -1;
        }




        //lépésnél változik a pozíció
        if (maxProfitX == 0) {
            if (maxProfitY % 2 == 0) {
                pos.y += plus;
            } else {
                pos.x += plus;
            }
        }

        int tempX = (pos.x) / macro, tempY = (pos.y) / macro;
        try {
            macroblock[tempX][tempY].value = 0;
        } catch (Exception e) {
            System.out.println(tempX + "    dsfd   " + tempY + " " + pos.toString());
        }
        for (int i = 1; i < 10 / macro + 1; ++i) {
            for (int l = -1 * i; l <= i; ++l) {
                if (dir % 2 == 0) {
                    tempX = pos.x / macro + l;
                    tempY = pos.y / macro + plus * i;
                } else {
                    tempX = pos.x / macro + plus * i;
                    tempY = pos.y / macro + l;
                }
                //TODO debuggolni és lehetne ezt breakelni
                /// System.out.println(tempX+ "po" + tempY + "asdfdsa"+ pos.x+ " "+pos.y +" " + plus);
                if (tempX > -1 && tempX < worldWidthMacro && tempY > -1 && tempY < worldHeigthMacro) {
                    macroblock[tempX][tempY].value = 0;
                }

            }

        }
        return dir;
    }

    private void refreshTiles() {
        lastChangeTurn = deepness;
        eating = 4;

        for (int i = 0; i < worldWidthMacro; i++) {
            for (int l = 0; l < worldHeigthMacro; l++) {
                if (macroblock[i][l].value < 4) {
                    macroblock[i][l].value++;
                }
            }
        }

    }

    public void ManageHostileAgent(Agent agent) {
        // Is it really hostile?
        if (agent.team != myTeamID) {
            //ha kint van ellenséges ágens a pályán kívűl akkor változott a pálya
            if (agent.position.isMoreThan(worldWidth, worldHeight)) {
                System.out.println("agent " + worldWidth + " h: " + worldHeight + " pos " + agent.position);
                thereWasMapSizeChange = true;
                lastKnowMapSizeChange = beliefs.thatTurn;
                boolean temp = worldHeightGrowing;
                if (worldHeight <= agent.position.y) {
                    worldHeight = agent.position.y + 1;
                    worldHeightGrowing = true;
                    System.out.println("hgrow true 1");
                }
                if (worldWidth <= agent.position.x) {
                    // azért kell mert ha egyébként is felderítünk akkor továbbra is derítsük a pályát.
                    if (worldHeight <= agent.position.y && !temp) {
                        worldHeightGrowing = false;
                    }
                    worldWidth = agent.position.x + 1;
                    worldWidthGrowing = true;
                    System.out.println("wgrow true 2");
                }
                fillEmptyBlocks();

            }


            // Is agent on list?
            int i;
            for (i = 0; i < Hostiles.size() && Hostiles.get(i).id != agent.id; i++);
            if (i == Hostiles.size()) {
                System.out.println("            állandóan változi k " + Hostiles.toString() + " myteam  " + myTeamID);
                Hostiles.add(agent);
            } else {
                Hostiles.get(i).RefreshIntel(agent, Friendlies.get(nowAgentIDInFriendlies));
            }
        }
    }

    /** aktualizálja a friendliesben a pozícióját és a látott ellenséges ágenseket
     * 
     * @param pos az adott ágens pozíciója
     * @param agents ágens lista
     */
    public void refreshAgents(Agent agent, ArrayList<Agent> agents) {
//        System.out.println(" agents " + agents.toString() + " " + Friendlies.toString());
        for (int i = 0; i < agents.size(); i++) {
            if (agents.get(i).team != myTeamID) {
                ManageHostileAgent(agents.get(i));
            } else {
                int l;
                for (l = 0; l < Friendlies.size(); l++) {
                    if (Friendlies.get(l).id == agent.id) {
                        //teamEnergy += agent.energy - Friendlies.get(l).energy;
//                        System.out.println("agen now őos " + Friendlies.get(l).position + " agnet si " + Friendlies.size());
                        nowAgentIDInFriendlies = l;
//                        System.out.println("11 " + Friendlies.get(l).toString());
//                        if(!agent.position.equals(Friendlies.get(l).position));
                        Friendlies.set(l, agent.setLastAgent(Friendlies.get(l)));
//                        System.out.println("22 " + Friendlies.get(l).toString());
                        break;
                    }
                }
                //System.out.println("l " + l + " size "+ Friendlies.size());
                if (l == Friendlies.size()) {
                    Friendlies.add(agents.get(i));
                    teamEnergy += agents.get(i).energy;
                }
            }
        }
        /* valszeg nem kell   int i;
        boolean inside = true;
        for(int l= 0; l < agents.size(); l++){
        for(i =0; i< Friendlies.size(); i++){
        if(Friendlies.get(i).id == agents.get(l).id){
        inside = false;
        Friendlies.set(i,Friendlies.get(i).setPos(pos)); //TODO nem csak a pozíciót beállítani
        }
        }
        System.out.println("refresh agent id " + i+ " now agent "+nowAgentID + " agents "+agents.toString()+ " friendlie " + Friendlies.toString());
        if(Friendlies.size() ==i){
        Friendlies.add(agents.get(l));
        }
        }*/
    }
}
